package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.mall.mapper.*;
import com.zenithmind.mall.pojo.dto.OrderDTO;
import com.zenithmind.mall.pojo.entity.*;
import com.zenithmind.mall.pojo.query.OrderQuery;
import com.zenithmind.mall.pojo.vo.OrderVO;
import com.zenithmind.mall.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final CartMapper cartMapper;
    private final ProductMapper productMapper;
    private final UserAddressMapper userAddressMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrder(OrderDTO orderDTO, String userId) {
        // 获取收货地址
        UserAddress address = userAddressMapper.selectById(orderDTO.getAddressId());
        if (address == null || !address.getUserId().equals(userId)) {
            throw new BusinessException("收货地址不存在");
        }

        // 获取订单商品
        List<OrderItemInfo> orderItems;
        if (orderDTO.getCartIds() != null && !orderDTO.getCartIds().isEmpty()) {
            // 从购物车下单
            LambdaQueryWrapper<Cart> cartWrapper = new LambdaQueryWrapper<>();
            cartWrapper.in(Cart::getId, orderDTO.getCartIds())
                       .eq(Cart::getUserId, userId)
                       .eq(Cart::getIsDeleted, 0);

            List<Cart> carts = cartMapper.selectList(cartWrapper);
            if (carts.size() != orderDTO.getCartIds().size()) {
                throw new BusinessException("购物车商品不存在");
            }

            orderItems = carts.stream().map(cart -> {
                Product product = productMapper.selectById(cart.getProductId());
                if (product == null || product.getStatus() != 1) {
                    throw new BusinessException("商品不存在或已下架");
                }
                if (product.getStock() < cart.getQuantity()) {
                    throw new BusinessException("商品库存不足");
                }

                OrderItemInfo itemInfo = new OrderItemInfo();
                itemInfo.setProductId(product.getId());
                itemInfo.setProductName(product.getName());
                itemInfo.setProductImage(product.getMainImage());
                itemInfo.setProductSku(product.getSku());
                itemInfo.setProductPrice(product.getPrice());
                itemInfo.setQuantity(cart.getQuantity());
                itemInfo.setSpecificationId(cart.getSpecificationId());
                return itemInfo;
            }).collect(Collectors.toList());
        } else if (orderDTO.getItems() != null && !orderDTO.getItems().isEmpty()) {
            // 直接购买
            orderItems = orderDTO.getItems().stream().map(item -> {
                Product product = productMapper.selectById(item.getProductId());
                if (product == null || product.getStatus() != 1) {
                    throw new BusinessException("商品不存在或已下架");
                }
                if (product.getStock() < item.getQuantity()) {
                    throw new BusinessException("商品库存不足");
                }

                OrderItemInfo itemInfo = new OrderItemInfo();
                itemInfo.setProductId(product.getId());
                itemInfo.setProductName(product.getName());
                itemInfo.setProductImage(product.getMainImage());
                itemInfo.setProductSku(product.getSku());
                itemInfo.setProductPrice(product.getPrice());
                itemInfo.setQuantity(item.getQuantity());
                itemInfo.setSpecificationId(item.getSpecificationId());
                return itemInfo;
            }).collect(Collectors.toList());
        } else {
            throw new BusinessException("订单商品不能为空");
        }

        if (orderItems.isEmpty()) {
            throw new BusinessException("订单商品不能为空");
        }

        // 计算订单金额
        BigDecimal productAmount = orderItems.stream()
                .map(item -> item.getProductPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal shippingFee = BigDecimal.ZERO; // 暂时免运费
        BigDecimal discountAmount = BigDecimal.ZERO; // 暂时无优惠
        BigDecimal paymentAmount = productAmount.add(shippingFee).subtract(discountAmount);

        // 创建订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo());
        order.setUserId(userId);
        order.setReceiverName(address.getReceiverName());
        order.setReceiverPhone(address.getReceiverPhone());
        order.setReceiverAddress(address.getDetailAddress());
        order.setReceiverAddressDetail(address.getProvince() + address.getCity() + address.getDistrict());
        order.setReceiverZip(address.getZipCode());
        order.setProductAmount(productAmount);
        order.setShippingFee(shippingFee);
        order.setDiscountAmount(discountAmount);
        order.setPaymentAmount(paymentAmount);
        order.setPaymentType(orderDTO.getPaymentType());
        order.setPaymentStatus(0); // 未支付
        order.setStatus(1); // 待支付
        order.setRemark(orderDTO.getRemark());
        order.setCouponId(orderDTO.getCouponId());
        order.setCreateBy(userId);

        if (!save(order)) {
            throw new BusinessException("创建订单失败");
        }

        // 创建订单详情
        for (OrderItemInfo itemInfo : orderItems) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(order.getId());
            orderItem.setProductId(itemInfo.getProductId());
            orderItem.setProductName(itemInfo.getProductName());
            orderItem.setProductImage(itemInfo.getProductImage());
            orderItem.setProductSku(itemInfo.getProductSku());
            orderItem.setProductPrice(itemInfo.getProductPrice());
            orderItem.setQuantity(itemInfo.getQuantity());
            orderItem.setTotalAmount(itemInfo.getProductPrice().multiply(BigDecimal.valueOf(itemInfo.getQuantity())));
            orderItem.setCreateBy(userId);
            orderItemMapper.insert(orderItem);

            // 减少库存
            LambdaUpdateWrapper<Product> productWrapper = new LambdaUpdateWrapper<>();
            productWrapper.eq(Product::getId, itemInfo.getProductId())
                         .ge(Product::getStock, itemInfo.getQuantity())
                         .setSql("stock = stock - " + itemInfo.getQuantity());

            boolean stockResult = productMapper.update(null, productWrapper) > 0;
            if (!stockResult) {
                throw new BusinessException("商品库存不足");
            }
        }

        // 如果是从购物车下单，删除购物车商品
        if (orderDTO.getCartIds() != null && !orderDTO.getCartIds().isEmpty()) {
            cartMapper.deleteBatchIds(orderDTO.getCartIds());
        }

        log.info("创建订单成功: {}", order.getId());
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean payOrder(String orderId, String userId) {
        Order order = getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (order.getStatus() != 1) {
            throw new BusinessException("订单状态不正确");
        }

        // 模拟支付成功
        order.setPaymentStatus(1); // 已支付
        order.setStatus(2); // 待发货
        order.setPaymentTime(LocalDateTime.now());
        order.setUpdateBy(userId);

        boolean result = updateById(order);
        if (result) {
            log.info("订单支付成功: {}", orderId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelOrder(String orderId, String reason, String userId) {
        Order order = getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (order.getStatus() != 1 && order.getStatus() != 2) {
            throw new BusinessException("订单状态不允许取消");
        }

        // 恢复库存
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.eq(OrderItem::getOrderId, orderId)
                   .eq(OrderItem::getIsDeleted, 0);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemWrapper);

        for (OrderItem item : orderItems) {
            LambdaUpdateWrapper<Product> productWrapper = new LambdaUpdateWrapper<>();
            productWrapper.eq(Product::getId, item.getProductId())
                         .setSql("stock = stock + " + item.getQuantity());
            productMapper.update(null, productWrapper);
        }

        order.setStatus(0); // 已取消
        order.setCancelTime(LocalDateTime.now());
        order.setCancelReason(reason);
        order.setUpdateBy(userId);

        boolean result = updateById(order);
        if (result) {
            log.info("订单取消成功: {}", orderId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean shipOrder(String orderId, String shippingCompany, String shippingNo) {
        Order order = getById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        if (order.getStatus() != 2) {
            throw new BusinessException("订单状态不正确");
        }

        order.setStatus(3); // 待收货
        order.setShipTime(LocalDateTime.now());
        order.setShippingCompany(shippingCompany);
        order.setShippingNo(shippingNo);
        order.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(order);
        if (result) {
            log.info("订单发货成功: {}", orderId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmReceive(String orderId, String userId) {
        Order order = getById(orderId);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        if (order.getStatus() != 3) {
            throw new BusinessException("订单状态不正确");
        }

        order.setStatus(4); // 待评价
        order.setReceiveTime(LocalDateTime.now());
        order.setUpdateBy(userId);

        boolean result = updateById(order);
        if (result) {
            log.info("确认收货成功: {}", orderId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean finishOrder(String orderId) {
        Order order = getById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        if (order.getStatus() != 4) {
            throw new BusinessException("订单状态不正确");
        }

        order.setStatus(5); // 已完成
        order.setFinishTime(LocalDateTime.now());
        order.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(order);
        if (result) {
            log.info("订单完成: {}", orderId);
        }
        return result;
    }

    @Override
    public PageResult<OrderVO> getOrderPage(OrderQuery query) {
        Page<Order> page = query.toPage();

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getIsDeleted, 0)
               .eq(StringUtils.hasText(query.getOrderNo()), Order::getOrderNo, query.getOrderNo())
               .eq(StringUtils.hasText(query.getUserId()), Order::getUserId, query.getUserId())
               .eq(query.getStatus() != null, Order::getStatus, query.getStatus())
               .eq(query.getPaymentStatus() != null, Order::getPaymentStatus, query.getPaymentStatus())
               .eq(query.getPaymentType() != null, Order::getPaymentType, query.getPaymentType())
               .like(StringUtils.hasText(query.getReceiverName()), Order::getReceiverName, query.getReceiverName())
               .like(StringUtils.hasText(query.getReceiverPhone()), Order::getReceiverPhone, query.getReceiverPhone())
               .ge(query.getStartTime() != null, Order::getCreateTime, query.getStartTime())
               .le(query.getEndTime() != null, Order::getCreateTime, query.getEndTime())
               .orderByDesc(Order::getCreateTime);

        Page<Order> result = page(page, wrapper);

        // 转换为VO
        List<OrderVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public OrderVO getOrderById(String id, String userId) {
        Order order = getById(id);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        return convertToVO(order);
    }

    @Override
    public OrderVO getOrderByNo(String orderNo, String userId) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOrderNo, orderNo)
               .eq(Order::getIsDeleted, 0);

        Order order = getOne(wrapper);
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("订单不存在");
        }
        return convertToVO(order);
    }

    @Override
    public Object getOrderStatistics(String userId) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId)
               .eq(Order::getIsDeleted, 0);

        List<Order> orders = list(wrapper);

        // 统计各状态订单数量
        long totalCount = orders.size();
        long pendingPayment = orders.stream().filter(o -> o.getStatus() == 1).count();
        long pendingShipment = orders.stream().filter(o -> o.getStatus() == 2).count();
        long pendingReceive = orders.stream().filter(o -> o.getStatus() == 3).count();
        long pendingReview = orders.stream().filter(o -> o.getStatus() == 4).count();
        long completed = orders.stream().filter(o -> o.getStatus() == 5).count();

        BigDecimal totalAmount = orders.stream()
                .filter(o -> o.getPaymentStatus() == 1)
                .map(Order::getPaymentAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return new OrderStatistics(totalCount, pendingPayment, pendingShipment,
                pendingReceive, pendingReview, completed, totalAmount);
    }

    @Override
    public Integer handleTimeoutOrders() {
        // 查询30分钟前创建且未支付的订单
        LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(30);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, 1) // 待支付
               .eq(Order::getIsDeleted, 0)
               .lt(Order::getCreateTime, timeoutTime);

        List<Order> timeoutOrders = list(wrapper);
        int count = 0;
        for (Order order : timeoutOrders) {
            try {
                cancelOrder(order.getId(), "订单超时自动取消", order.getUserId());
                count++;
            } catch (Exception e) {
                log.error("处理超时订单失败: {}", order.getId(), e);
            }
        }
        return count;
    }

    @Override
    public Integer autoConfirmOrders() {
        // 查询7天前发货且未确认收货的订单
        LocalDateTime autoConfirmTime = LocalDateTime.now().minusDays(7);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, 3) // 待收货
               .eq(Order::getIsDeleted, 0)
               .lt(Order::getShipTime, autoConfirmTime);

        List<Order> orders = list(wrapper);
        int count = 0;
        for (Order order : orders) {
            try {
                confirmReceive(order.getId(), order.getUserId());
                count++;
            } catch (Exception e) {
                log.error("自动确认收货失败: {}", order.getId(), e);
            }
        }
        return count;
    }

    @Override
    public Integer autoReviewOrders() {
        // 查询15天前确认收货且未完成的订单
        LocalDateTime autoReviewTime = LocalDateTime.now().minusDays(15);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, 4) // 待评价
               .eq(Order::getIsDeleted, 0)
               .lt(Order::getReceiveTime, autoReviewTime);

        List<Order> orders = list(wrapper);
        int count = 0;
        for (Order order : orders) {
            try {
                finishOrder(order.getId());
                count++;
            } catch (Exception e) {
                log.error("自动好评失败: {}", order.getId(), e);
            }
        }
        return count;
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.valueOf((int) (Math.random() * 9000) + 1000);
        return "ZM" + timestamp + random;
    }

    /**
     * 转换为VO
     */
    private OrderVO convertToVO(Order order) {
        OrderVO vo = new OrderVO();
        BeanUtils.copyProperties(order, vo);

        // 设置状态文本
        vo.setStatusText(getStatusText(order.getStatus()));
        vo.setPaymentStatusText(getPaymentStatusText(order.getPaymentStatus()));
        vo.setPaymentTypeText(getPaymentTypeText(order.getPaymentType()));

        // 设置收货人信息
        OrderVO.ReceiverInfo receiverInfo = new OrderVO.ReceiverInfo();
        receiverInfo.setName(order.getReceiverName());
        receiverInfo.setPhone(order.getReceiverPhone());
        receiverInfo.setAddress(order.getReceiverAddress());
        receiverInfo.setAddressDetail(order.getReceiverAddressDetail());
        receiverInfo.setZip(order.getReceiverZip());
        vo.setReceiverInfo(receiverInfo);

        // 设置物流信息
        if (StringUtils.hasText(order.getShippingCompany())) {
            OrderVO.ShippingInfo shippingInfo = new OrderVO.ShippingInfo();
            shippingInfo.setCompany(order.getShippingCompany());
            shippingInfo.setNo(order.getShippingNo());
            shippingInfo.setShipTime(order.getShipTime());
            shippingInfo.setReceiveTime(order.getReceiveTime());
            vo.setShippingInfo(shippingInfo);
        }

        // 设置优惠券信息
        if (StringUtils.hasText(order.getCouponId())) {
            OrderVO.CouponInfo couponInfo = new OrderVO.CouponInfo();
            couponInfo.setId(order.getCouponId());
            couponInfo.setAmount(order.getCouponAmount());
            vo.setCouponInfo(couponInfo);
        }

        // 设置时间信息
        OrderVO.TimeInfo timeInfo = new OrderVO.TimeInfo();
        timeInfo.setCreateTime(order.getCreateTime());
        timeInfo.setPaymentTime(order.getPaymentTime());
        timeInfo.setShipTime(order.getShipTime());
        timeInfo.setReceiveTime(order.getReceiveTime());
        timeInfo.setFinishTime(order.getFinishTime());
        timeInfo.setCancelTime(order.getCancelTime());
        vo.setTimeInfo(timeInfo);

        // 查询订单详情
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.eq(OrderItem::getOrderId, order.getId())
                   .eq(OrderItem::getIsDeleted, 0);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemWrapper);

        List<com.zenithmind.mall.pojo.vo.OrderItemVO> itemVOs = orderItems.stream()
                .map(this::convertItemToVO)
                .collect(Collectors.toList());
        vo.setItems(itemVOs);

        return vo;
    }

    /**
     * 转换订单详情为VO
     */
    private com.zenithmind.mall.pojo.vo.OrderItemVO convertItemToVO(OrderItem item) {
        com.zenithmind.mall.pojo.vo.OrderItemVO vo = new com.zenithmind.mall.pojo.vo.OrderItemVO();
        BeanUtils.copyProperties(item, vo);
        return vo;
    }

    /**
     * 获取订单状态文本
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 0: return "已取消";
            case 1: return "待支付";
            case 2: return "待发货";
            case 3: return "待收货";
            case 4: return "待评价";
            case 5: return "已完成";
            default: return "未知";
        }
    }

    /**
     * 获取支付状态文本
     */
    private String getPaymentStatusText(Integer paymentStatus) {
        switch (paymentStatus) {
            case 0: return "未支付";
            case 1: return "已支付";
            case 2: return "支付失败";
            case 3: return "已退款";
            default: return "未知";
        }
    }

    /**
     * 获取支付方式文本
     */
    private String getPaymentTypeText(Integer paymentType) {
        switch (paymentType) {
            case 1: return "支付宝";
            case 2: return "微信支付";
            case 3: return "余额支付";
            default: return "未知";
        }
    }

    /**
     * 订单统计类
     */
    public static class OrderStatistics {
        private Long totalCount;
        private Long pendingPayment;
        private Long pendingShipment;
        private Long pendingReceive;
        private Long pendingReview;
        private Long completed;
        private BigDecimal totalAmount;

        public OrderStatistics(Long totalCount, Long pendingPayment, Long pendingShipment,
                             Long pendingReceive, Long pendingReview, Long completed, BigDecimal totalAmount) {
            this.totalCount = totalCount;
            this.pendingPayment = pendingPayment;
            this.pendingShipment = pendingShipment;
            this.pendingReceive = pendingReceive;
            this.pendingReview = pendingReview;
            this.completed = completed;
            this.totalAmount = totalAmount;
        }

        // getters and setters
        public Long getTotalCount() { return totalCount; }
        public void setTotalCount(Long totalCount) { this.totalCount = totalCount; }

        public Long getPendingPayment() { return pendingPayment; }
        public void setPendingPayment(Long pendingPayment) { this.pendingPayment = pendingPayment; }

        public Long getPendingShipment() { return pendingShipment; }
        public void setPendingShipment(Long pendingShipment) { this.pendingShipment = pendingShipment; }

        public Long getPendingReceive() { return pendingReceive; }
        public void setPendingReceive(Long pendingReceive) { this.pendingReceive = pendingReceive; }

        public Long getPendingReview() { return pendingReview; }
        public void setPendingReview(Long pendingReview) { this.pendingReview = pendingReview; }

        public Long getCompleted() { return completed; }
        public void setCompleted(Long completed) { this.completed = completed; }

        public BigDecimal getTotalAmount() { return totalAmount; }
        public void setTotalAmount(BigDecimal totalAmount) { this.totalAmount = totalAmount; }
    }

    /**
     * 订单商品信息内部类
     */
    private static class OrderItemInfo {
        private String productId;
        private String productName;
        private String productImage;
        private String productSku;
        private BigDecimal productPrice;
        private Integer quantity;
        private String specificationId;

        // getters and setters
        public String getProductId() { return productId; }
        public void setProductId(String productId) { this.productId = productId; }

        public String getProductName() { return productName; }
        public void setProductName(String productName) { this.productName = productName; }

        public String getProductImage() { return productImage; }
        public void setProductImage(String productImage) { this.productImage = productImage; }

        public String getProductSku() { return productSku; }
        public void setProductSku(String productSku) { this.productSku = productSku; }

        public BigDecimal getProductPrice() { return productPrice; }
        public void setProductPrice(BigDecimal productPrice) { this.productPrice = productPrice; }

        public Integer getQuantity() { return quantity; }
        public void setQuantity(Integer quantity) { this.quantity = quantity; }

        public String getSpecificationId() { return specificationId; }
        public void setSpecificationId(String specificationId) { this.specificationId = specificationId; }
    }
}
